package com.dongdongshop.service.impl;

import com.dongdongshop.pojo.TbItem;
import com.dongdongshop.pojo.TbOrderItem;
import com.dongdongshop.service.CartService;
import com.dongdongshop.service.TbItemService;
import com.dongdongshop.vo.CartVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Service
@DubboService
public class CartServiceImpl implements CartService {

    @DubboReference
    private TbItemService itemService;

    @Autowired
    private RedisTemplate redisTemplate;


    //调用购物车服务,添加购物车数据
    @Override
    public List<CartVo> addCart(List<CartVo> cartVoList, Long skuId, Integer num) {

        // 1: 调用 goods 服务,获取数据 item
        TbItem item = itemService.selectById(skuId);

        // 2: 就能拿到 item 商家id
        String sellerId = item.getSellerId();

        // 3: 根据商家 id 判断此用户有没有买过这个商家的商品
        CartVo vo = getCartVoBySellerId(cartVoList,sellerId);

        if (vo == null){
            // 3.1 没有 购物车之前没有添加过这个商家的商品 直接往购物车里面存放数据即可

            vo = new CartVo();
            //添加数据返回
            vo.setSellerId(sellerId); //添加商家id

            TbOrderItem orderItem = createTbOrderItem( num, item); //组装购物车明细数据

            List<TbOrderItem> orderItemList = new ArrayList<>(); //创建 list 集合来装明细表数据
            orderItemList.add(orderItem);
            vo.setOrderItemList(orderItemList);


            //将 创建好的 vo 对象 添加到 购物车列表中 CartVo
            cartVoList.add(vo);
        }else {
            // 3.2 有 说明 购物车有信息,从购物车信息中查看一下是否买过这件商品
            List<TbOrderItem> orderItemList = vo.getOrderItemList();

            // 调用方法  根据 商品id 查询出用户购物车中是否买过此商品
            TbOrderItem orderItem = getOrderItemBySkuId(orderItemList,skuId);

            if (orderItem == null){
                // 3.2.1 表名用户未买此商品 , 但已经在该商家买过其他商品, 直接在 CartVo 里面的 list 追加一条信息即可

                orderItem = createTbOrderItem( num, item);

                orderItemList.add(orderItem);
            }else {
                // 3.2.2 表示客户已经买过此商品, 但需要加购 ; 需要计算出总数量和总价格
                // 修改总数量
                orderItem.setNum(orderItem.getNum() + num); // 用户原来买过的数量 + 现在又买的数量
                //修改总价格
                orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue() * orderItem.getNum()));

                //如果客户 购买数量小于 0 的话, 将这件商品从购物车里面移出去
                if (orderItem.getNum() <= 0){
                    orderItemList.remove(orderItem);
                }

                //如果客户购买商家的数量小于等于 0 的话, 将信息移除出去
                if (orderItemList.size() == 0){
                    cartVoList.remove(vo);
                }

            }
        }

        return cartVoList;
    }


    /**
     *  根据用户 id 查取 Redis 中购物车信息
     * @param id
     * @return
     */
    @Override
    public List<CartVo> getCartListFromRedis(Long id) {
        List<CartVo> cartList = (List<CartVo>) redisTemplate.boundHashOps("cartList").get(id);
        if (cartList == null){
            return new ArrayList<>();
        }
        return cartList;
    }


    /**
     *  将购物车信息存放到 redis 中
     * @param id
     * @param cartVoList
     */
    @Override
    public void addCartToRedis(Long id, List<CartVo> cartVoList) {
        redisTemplate.boundHashOps("cartList").put(id,cartVoList);
    }


    // 将 cookie 中的购物车信息和 redis 中的购物车信息进行合并

    /**
     *   将 cookie 中的购物车信息和 redis 中的购物车信息进行合并
     * @param cartVoCookie  cookie 中的购物车信息
     * @param cartVoRedis  redis 中的购物车信息
     * @return
     */
    @Override
    public List<CartVo> mergeCartList(List<CartVo> cartVoCookie, List<CartVo> cartVoRedis) {
        for (CartVo cartVoRedi : cartVoRedis) {
            List<TbOrderItem> orderItemList = cartVoRedi.getOrderItemList();
            for (TbOrderItem orderItem : orderItemList) {
                cartVoCookie = addCart(cartVoCookie,orderItem.getItemId(),orderItem.getNum());
            }
        }
        return cartVoCookie;
    }

    /**
     *  封装购物车表
     * @param num  购买的数量
     * @param item 商品表
     * @return
     */
    private TbOrderItem createTbOrderItem( Integer num, TbItem item) {
        TbOrderItem orderItem = new TbOrderItem();
        orderItem.setItemId(item.getId()); // 添加skuid

        orderItem.setGoodsId(item.getGoodsId()); //添加商品id

        orderItem.setPrice(item.getPrice()); //添加商品价格

        orderItem.setNum(num);  // 添加商品数量

        orderItem.setPicPath(item.getImage()); //添加商品图片

        orderItem.setTitle(item.getTitle()); //添加商品名称

        orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num)); //计算总价

        orderItem.setSellerId(item.getSellerId()); //添加商家 id

        return orderItem;
    }

    /**
     *   根据 商品id 查询出用户购物车中是否买过此商品
     * @param orderItemList 购物车数据
     * @param skuId 商品id
     * @return
     */
    private TbOrderItem getOrderItemBySkuId(List<TbOrderItem> orderItemList, Long skuId) {
        return orderItemList.stream().filter(orderItem -> skuId.equals(orderItem.getItemId())).findFirst().orElse(null);
        /*for (TbOrderItem orderItem : orderItemList) {
            if (skuId.equals(orderItem.getItemId())){
                return orderItem;
            }
        }
        return null;*/
    }



    /**
     *  根据 商家id 判断此用户在购物车中有没有添加该商家商品信息
     * @param cartVoList  购物车数据
     * @param sellerId 商家id
     * @return
     */
    private CartVo getCartVoBySellerId(List<CartVo> cartVoList, String sellerId) {
        return cartVoList.stream().filter(cartVo -> cartVo.getSellerId().equals(sellerId)).findFirst().orElse(null);
        /*for (CartVo cartVo : cartVoList) {
            if (cartVo.getSellerId().equals(sellerId)){
                return cartVo;
            }
        }
        return null;*/
    }
}
